package com.augmentum.login.common;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.augmentum.login.AppContent;
import com.augmentum.login.Constants;
import com.augmentum.login.exception.DBException;
import com.augmentum.login.util.DBUtil;

public class JDBCTemplate<T> {

    public JDBCTemplate() {

    }

    public int upate(String sql, JDBCCallback<T> callback) {
        PreparedStatement stmt = null;
        Connection conn = null;
        int count = 0;
        boolean needMyClose = false;
        try {
            ConnectionHolder connectionHolder = (ConnectionHolder)AppContent.getAppContent().getObject(Constants.JDBC_CONNECTION);
            if (connectionHolder != null) {
                conn = connectionHolder.getConn();
            }
            if (conn == null) {
                conn = DBUtil.getConnection();
                needMyClose = true;
            }
            stmt = conn.prepareStatement(sql);
            callback.setStatement(stmt);
            count = stmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.closeDBConnection(null, stmt, null);
            if (needMyClose) {
                DBUtil.closeDBConnection(null, null, conn);
            }
        }
        return count;
    }

    public void Save(String sql, JDBCCallback<T> callback) {
        PreparedStatement stmt = null;
        Connection conn = null;
        boolean needMyClose = false;
        try {
            ConnectionHolder connectionHolder = (ConnectionHolder)AppContent.getAppContent().getObject(Constants.JDBC_CONNECTION);
            if (connectionHolder != null) {
                conn = connectionHolder.getConn();
            }
            if (conn == null) {
                conn = DBUtil.getConnection();
                needMyClose = true;
            }

            stmt = conn.prepareStatement(sql);
            callback.setStatement(stmt);
            stmt.execute();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.closeDBConnection(null, stmt, null);
            if (needMyClose) {
                DBUtil.closeDBConnection(null, null, conn);
            }
        }
    }

    public void detele(String sql, JDBCCallback<T> callback) {
        PreparedStatement stmt = null;
        Connection conn = null;
        boolean needMyClose = false;
        try {
            ConnectionHolder connectionHolder = (ConnectionHolder)AppContent.getAppContent().getObject(Constants.JDBC_CONNECTION);
            if (connectionHolder != null) {
                conn = connectionHolder.getConn();
            }
            if (conn == null) {
                conn = DBUtil.getConnection();
                needMyClose = true;
            }
            stmt = conn.prepareStatement(sql);
            callback.setStatement(stmt);
            stmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.closeDBConnection(null, stmt, null);
            if (needMyClose) {
                DBUtil.closeDBConnection(null, null, conn);
            }
        }
    }

    public T getT(String sql, JDBCCallback<T> callback) {
        PreparedStatement stmt = null;
        ResultSet rst = null;
        Connection conn = null;
        boolean needMyClose = false;
        T t = null;
        try {
            ConnectionHolder connectionHolder = (ConnectionHolder)AppContent.getAppContent().getObject(Constants.JDBC_CONNECTION);
            if (connectionHolder != null) {
                conn = connectionHolder.getConn();
            }
            if (conn == null) {
                conn = DBUtil.getConnection();
                needMyClose = true;
            }
            stmt = conn.prepareStatement(sql);
            callback.setStatement(stmt);
            rst = stmt.executeQuery();
            if (rst.next()) {
                t = callback.rsToObject(rst);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.closeDBConnection(rst, stmt, null);
            if (needMyClose) {
                DBUtil.closeDBConnection(null, null, conn);
            }
        }
        return t;
    }

    public List<T> getList(String sql, JDBCCallback<T> callback) {
        PreparedStatement stmt = null;
        ResultSet rst = null;
        Connection conn = null;
        boolean needMyClose = false;
        List<T> list = new ArrayList<T>();
        try {
            ConnectionHolder connectionHolder = (ConnectionHolder)AppContent.getAppContent().getObject(Constants.JDBC_CONNECTION);
            if (connectionHolder != null) {
                conn = connectionHolder.getConn();
            }
            if (conn == null) {
                conn = DBUtil.getConnection();
                needMyClose = true;
            }
            stmt = conn.prepareStatement(sql);
            callback.setStatement(stmt);
            rst = stmt.executeQuery();
            while (rst.next()) {
                list.add(callback.rsToObject(rst));
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DBException();
        } finally {
            DBUtil.closeDBConnection(rst, stmt, null);
            if (needMyClose) {
                DBUtil.closeDBConnection(null, null, conn);
            }
        }
        return list;
    }
}
